<?php
Zend::loadClass('Lead_EDO_Datatype_Relation');

class Lead_EDO_Datatype_Relation_BelongsTo extends Lead_EDO_Datatype_Relation
{
    
    private $_foreignKeyValue;
   	
    private $_assocObj;
   	
    
    private $_options;
    
    
    public static $_stored_objs = array();
    
    
    public function __construct(Lead_EDO_Object_Abstract $owner, $config = array())
	{
		parent::__construct($owner, $config);
		$this->_foreignKey = (isset($config['foreign_key'])) ? $config['foreign_key'] : $config['class_name'] . '_id';
		$this->getOwner()->attach($this, 'afterFetch', '_afterFetchActions');
		$this->getOwner()->getFieldObject($this->getForeignKey())->attach($this, 'onChange', '_onForeignKeyChange');
	}
	
	
	public function _onForeignKeyChange()
	{
	   	    
	   $this->_assocObj = null;
       $this->_foreignKeyValue = $this->getOwner()->getField($this->getForeignKey());

	}
	

	
	public function _afterFetchActions()
	{
	    $this->_assocObj = null;
	    $this->_foreignKeyValue = $this->getOwner()->getField($this->getForeignKey());
	    
        $rargs = $this->parseConditions();
        foreach($rargs as $rarg)
        {
            $rarg[2] = trim($rarg[2], '%#');
            $fObj = $this->getOwner()->getFieldObject($rarg[2])->attach($this, 'onChange', '_nullify');
        }
	}
	
	
	public function _nullify()
	{
	    $this->getowner()->setField($this->getForeignKey(), null);
	}
	
	
	
	
	public function isNull()
	{
	    return (is_null($this->_foreignKeyValue));
	}
	
	
	
	public function getValue()
	{
        
	    
	    if(!$this->_assocObj)
        {

                       
           if($this->isNull())
	       {
	           return null;
	       }
                 
            if(key_exists($this->_foreignKeyValue, self::$_stored_objs) AND true == false)
            {
                $this->_assocObj =& self::$_stored_objs[$this->_foreignKeyValue];
            }
            else 
            {                   
                if(!$this->_looseBind)
                {
                	$assocObj = $this->getOwner()->getHandler()->get($this->getClassName());
                	$assocObj->fetch($this->_foreignKeyValue);
                }else{
                	$assocObj = $this->getOwner()->getHandler()->fetch($this->_foreignKeyValue);
                }
                
                // self::$_stored_objs[$this->_foreignKeyValue] = $assocObj;
                // $this->_assocObj = self::$_stored_objs[$this->_foreignKeyValue];
                $this->_assocObj = $assocObj;
            }
                       
            // print "<hr />";
            
        }
	    
	    return $this->_assocObj;
	    
	}
	
	
	public function getOptions()
	{
        	    
	    if(!isset(EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()]))
	    {
           $args = $this->parseConditionsToValues();
           
           
           $obj = $this->getOwner()->getHandler()->get($this->getClassName());

           foreach($args as $arg)
                $obj->getFinder()->addCondition($arg[0], $arg[1], $arg[2]);
           
           if($this->getConfig('order'))
           {
               $obj->getFinder()->addOrderer($this->getConfig('order'));
           }
 
           
           $query = $obj->getFinder()->getQuery();
                                 
           $display = $this->getConfig('display');
           $regexp = "/(\%([a-zA-Z_]*))/si";
           preg_match_all($regexp, $display, $fields);
           $fields = $fields[2];
           $fields = array_unique($fields);
           foreach($fields as $field)
           {
               $table = $obj->getFieldsTable($field);
               
               $query->addField("{$table}.{$field}", false);
                                             
               if(!$query->tableIsJoined($table))
                    $query->addJoin($table, 'INNER', "edo.id = {$table}.id");
           }
          
           $result = $query->ldb->getAll($query->getSQL());
           
           
           
           $opzions = array();
           foreach($result as $row)
           {
               $display2 = $display;
               foreach($fields as $field)
               {
                    $display2 = str_ireplace("%{$field}", $row[$field], $display2);
               }
               $opzions[$row['id']] = $display2;
           }
           
          
                               
           /*           
           $options = $obj->getFinder()->findAll($args, false, 'fast2');
       
	       $opzions = array();
           foreach($options as $obj)
	       {
	          $opzions[$obj->id] = $this->resolveTags($obj, $this->getConfig('display'));
	       }
	       */
           
	       EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()] = $opzions;

	    }
	    
	    return EDO::$relationOptions[$this->getOwner()->getClass()][$this->getName()];
	}
	
	
	public function setValue($value, $validate = true)
	{
    
	    if($validate)
            $value = $this->validate($value);
            
        if($value !== false)    
        {
            $this->getOwner()->setField($this->getForeignKey(), $value);    
        }
           
        
        
        return ($value === false) ? false : true;
	}
	
	
	
	public function set(EDO_object_base $assocObj)
	{
	    	    
	    $this->_assocObj = $assocObj;
	    	    
	    
	}
	
	
	public function validate($value)
	{
	    if(empty($value))
	       return null;
	    	    
	    if(is_numeric($value))
	    {
	       $this->getOwner()->setField($this->getForeignKey(), $value);
	       return $value;    
	    }
	    else 
	    {

	        if(is_array($value))  
	           return null;

	        $options = $this->getOptions();
       	        
	        
	        return array_search($value, $options);
	        
	    }
	    
	    

	}
	
	
	
	public function joinTo(Query $query)
	{
	    $obj = $this->getOwner()->edo->get($this->getClassName());
        $tables = $obj->getTables();
        
        $args = $this->parseConditionsToTables();
        
        if($args)
        {
            
            
            $wg = $query->addWhereGroup();
            foreach($args as $argArr)
            {
               $argTbl = $obj->getFieldsTable($argArr[0]);
               $argArr[0] = $argTbl . '.' . $argArr[0];
               	        
                call_user_func_array(array($wg, 'addWhereCond'), $argArr);    
            }
        }
	    	           
        $fKeyTable = $this->getOwner()->getFieldObject($this->getForeignKey())->getTable();

       
        
        
        $firstTable = array_shift($tables);
        $query->addJoin($firstTable, 'INNER', "{$this->getOwner()->getFirstTable()}.{$this->getForeignKey()} = {$obj->getFirstTable()}.id");
        
        foreach($tables as $table)
        {
            $query->addJoin($table, 'INNER', "{$firstTable}.id = {$table}.id");
        }
       

	    
	    
	}
	
	
	
	public function getOpposite()
	{
	   $obj = $this->getOwner()->edo->get($this->getClassName());
       foreach($obj->getRelationObjects() as $relObj) 
       {
           if($relObj->getForeignKey() == $this->getForeignKey())
            return $obj->getClass() . '_' . $relObj->getName();
       }
	   	    
	}

    
}